package com.jijia.webbase.controller;

import cn.hutool.json.JSONUtil;
import com.jijia.webbase.config.response.JsonResult;
import com.jijia.webbase.config.security.LoginUser;
import com.jijia.webbase.config.security.SaveLoginUser;
import com.jijia.webbase.domain.User;
import com.jijia.webbase.domain.params.Test;
import com.jijia.webbase.mapper.UserMapper;
import com.jijia.webbase.service.impl.UserService;
import com.jijia.webbase.utils.JwtUtil;
import com.jijia.webbase.utils.ThreadLocalUtil;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.time.Duration;
import java.util.HashMap;

import static com.fasterxml.jackson.databind.type.LogicalType.Map;

// AuthController.java
// 7. 登录接口
@Slf4j
@RestController
@Validated
public class AuthController {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserService userService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtil jwtUtil;

//    @PostMapping("/login")
//    public JsonResult login(@RequestBody User user) {
//        log.debug("login user: {}", user);
//        // Spring Security认证流程
//        Authentication authentication = null;
//        try {
//            log.debug("Attempting to authenticate user: {}", user.getUserName());
//           authentication = authenticationManager.authenticate(
//                    new UsernamePasswordAuthenticationToken(
//                            user.getUserName(),
//                            user.getUserPassword()
//                    )
//            );
//            log.debug("login 认证结果: {}", authentication);
//
//        } catch (LockedException e) {
//            log.error("User account is locked for user: {}", user.getUserName(), e);
//            return JsonResult.ok("User account is locked");
//        } catch (Exception e) {
//            log.error("Authentication failed for user: {}", user.getUserName(), e);
//            return JsonResult.ok("Authentication failed");
//        }
//
//        // 生成JWT
//        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
//
//        String token = jwtUtil.generateToken(loginUser);
//        loginUser.setToken(token);
//        log.debug("未序列化 {}", loginUser);
//        log.debug("序列化 {}", JSONUtil.toJsonStr(loginUser));
//
//        log.debug("序列化 角色: {}", JSONUtil.toJsonStr(loginUser.getAuthorities().toString()));
//        SaveLoginUser saveLoginUser = new SaveLoginUser();
//        BeanUtils.copyProperties(loginUser,saveLoginUser);
//        // 存储到Redis
//        jwtUtil.storeUserWithToken("token_"+loginUser.getUsername(), saveLoginUser);
//
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("token", token);
//
//        return JsonResult.ok(map);
//    }

    @PostMapping("/login")
    public JsonResult login(HttpServletResponse response) {
        log.debug("控制器中 ");
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        // 生成JWT
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();

        String token = jwtUtil.generateToken(loginUser);
        loginUser.setToken(token);
//        log.debug("未序列化 {}", loginUser);
//        log.debug("序列化 {}", JSONUtil.toJsonStr(loginUser));
//
//        log.debug("序列化 角色: {}", JSONUtil.toJsonStr(loginUser.getAuthorities().toString()));
        SaveLoginUser saveLoginUser = new SaveLoginUser();
        BeanUtils.copyProperties(loginUser,saveLoginUser);
        // 存储到Redis
        jwtUtil.storeUserWithToken("token_"+loginUser.getUsername(), saveLoginUser);


        // 设置 token 到响应的 Cookie 中
        Cookie cookie = new Cookie("token", token);
        cookie.setHttpOnly(true); // 防止 JavaScript 访问该 cookie
        cookie.setSecure(true);   // 如果使用 HTTPS，设置为 true
        cookie.setPath("/");      // 设置 cookie 的路径为根路径，保证在整个站点都能访问
        cookie.setMaxAge(60 * 60 * 24); // 设置 cookie 的有效期为 1 天

        // 将 Cookie 添加到响应头中
        response.addCookie(cookie);


//        HashMap<String, Object> map = new HashMap<>();
//        map.put("token", token);
//        map.put("userName", saveLoginUser.getUser().getUserName());

        return JsonResult.ok();
    }




//    注册
    @PostMapping("/register")
    public JsonResult register(@RequestBody  User user) {
        log.debug("register user: {}", user);
        user.setUserPassword(passwordEncoder.encode(user.getUserPassword()));
        return JsonResult.ok(userMapper.registerUser(user)==1?"注册成功":"注册失败");
    }

    @PostMapping("/logout")
    public JsonResult logout(HttpServletResponse response) {
        SaveLoginUser loginUser = (SaveLoginUser) ThreadLocalUtil.get().get("user");
        log.debug("logout loginUser: {}", loginUser);
        // 删除Redis
        jwtUtil.deleteKey("token_"+loginUser.getUser().getUserName());

        Cookie cookie = new Cookie("token", "");
        cookie.setMaxAge(0);
        cookie.setPath("/");
        response.addCookie(cookie);

        return JsonResult.ok("退出成功");
    }


    @GetMapping("/getUserInfo")
    public JsonResult getUserInfo() {
        SaveLoginUser userInfo = (SaveLoginUser)ThreadLocalUtil.get().get("user");
        String userName = userInfo.getUser().getUserName();
        User user = userService.getUserByUserName(userName);
//        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//        SaveLoginUser loginUser = (SaveLoginUser) authentication.getPrincipal();
//        log.debug("test loginUser: {}", loginUser);
        return JsonResult.ok(user);
    }

    @GetMapping("/getAllUserInfo")
    public JsonResult getAllUserInfo() {
        User[] users = userService.getAllUserInfo();
//        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//        SaveLoginUser loginUser = (SaveLoginUser) authentication.getPrincipal();
//        log.debug("test loginUser: {}", loginUser);
        return JsonResult.ok(users);
    }
}